package main

import (
	"fmt"
	"reflect"
	"strings"
	"time"

	"github.com/go-playground/validator/v10"
)

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func MyNotBlank(fl validator.FieldLevel) bool {
	field := fl.Field()
	switch field.Kind() {
	case reflect.String:
		return len(strings.TrimSpace(field.String())) > 0
	case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array:
		return field.Len() > 0
	case reflect.Ptr, reflect.Interface, reflect.Func:
		return !field.IsNil()
	default:
		return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
	}
}

func main() {
	validate = validator.New()
	validate.RegisterValidation("yourtag", MyNotBlank)
	now := time.Now()

	inner := &Inner{
		StartDate: now,
	}

	outer := &Outer{
		InnerStructField: inner,
		CreatedAt:        now,
		Age:              0,
		Stat:             3,
		Hobby:            []string{"a", "b"},
		Name:             "keke dd",
		Birth:            "2023-05-18",
	}

	errs := validate.Struct(outer)
	fmt.Println(errs)
}

type Inner struct {
	StartDate time.Time
}

type Outer struct {
	InnerStructField *Inner
	CreatedAt        time.Time `validate:"ltecsfield=InnerStructField.StartDate"`
	Age              int       `validate:"required_if=Stat 1"`
	Stat             int       `validate:"oneof=1 3 5"`
	Hobby            []string  `validate:""`
	Name             string    `validate:"oneof='keke dd' dd"`
	Birth            string    `validate:"datetime=2006-01-02,yourtag"`
}
